﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FooFun.GrantFrameworks;
using System.Data;

namespace AccessGrant
{
    public class PermissionQuery : IPermissionQuery<int, int, int>
    {
        IPermissionQuery<int, int, int> query;

        public PermissionQuery()
        {
            query = DaoPermissionQuery.Init();

            dataService = DataService.GetData();
        }

        #region IPermissionQuery<int,int,int> 成员

        public PermissionSet this[int obj, int account, int per]
        {
            get
            {
                IList<int> accountList = this.ListAccount();
                IList<int> perList = this.ListPermission();

                IMatrix<PermissionSet, int, int> objMatrix
                    = new DicMatrix();

                foreach (int accountId in accountList)
                {
                    foreach (int perId in perList)
                    {
                        PermissionSet set = query[obj, accountId, perId];
                        int parentId = obj;

                        while (set == PermissionSet.NotSet
                            && parentId != 0)
                        {
                            parentId = GetParentObjId(parentId);
                            set = query[parentId, accountId, perId];
                        }

                        objMatrix[accountId, perId] = set;
                    }
                }

                Dictionary<int, PermissionSet> map
                    = new Dictionary<int, PermissionSet>();

                foreach (int accountId in this.ListAccount())
                {
                    map[accountId] = objMatrix[accountId, per];
                }

                PermissionSet result = PermissionSet.NotSet;

                IList<int> list = ListParentAccountId(account);
                foreach (int parentId in list)
                {
                    if (map.ContainsKey(parentId))
                    {
                        result
                            = CoverPermission(result, map[parentId]);
                    }
                }

                return result;
            }
        }

        private PermissionSet CoverPermission
            (PermissionSet target, PermissionSet newSet)
        {
            switch (target)
            {
                case PermissionSet.NotSet:
                    return newSet;
                case PermissionSet.Grant:
                    switch (newSet)
                    {
                        case PermissionSet.NotSet:
                            return PermissionSet.Grant;

                        case PermissionSet.Grant:
                            return PermissionSet.Grant;

                        case PermissionSet.Revoke:
                            return PermissionSet.Revoke;

                        default:
                            return PermissionSet.Grant;
                    }

                case PermissionSet.Revoke:
                    return PermissionSet.Revoke;
                default:
                    return PermissionSet.NotSet;
            }
        }


        DataService dataService;
        public int GetParentObjId(int id)
        {
            return dataService.GetForumParentId(id);
        }

        public IList<int> ListParentAccountId(int id)
        {
            return DataService.GetData().ListAccountId(id);
        }

        public IList<int> ListObject()
        {
            return query.ListObject();
        }

        public IList<int> ListAccount()
        {
            return query.ListAccount();
        }

        public IList<int> ListPermission()
        {
            return query.ListPermission();
        }

        public IList<Permission> ListPermissions()
        {
            return ((DaoPermissionQuery)query).ListPermissions();
        }

        #endregion
    }
}
